package com.android.basiclib.base.vm

import android.text.TextUtils
import com.android.basiclib.R
import com.android.basiclib.bean.BaseBean
import com.android.basiclib.utils.CommUtils
import com.google.gson.JsonParseException
import com.android.basiclib.bean.OkResult
import com.android.basiclib.core.BaseLibCore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import retrofit2.HttpException
import java.io.IOException
import java.net.ConnectException
import java.net.SocketException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

open class BaseRepository {

    //无异常处理 -> 一般不用这个，内部没有捕获异常 一旦报错会导致App崩溃
    suspend inline fun <T : Any> handleApiCall(call: suspend () -> BaseBean<T>): BaseBean<T> {
        return call.invoke()
    }

    //处理Http错误-内部再处理Api错误
    suspend fun <T : Any> handleErrorApiCall(call: suspend () -> OkResult<T>, errorMessage: String = ""): OkResult<T> {
        return try {
            call()
        } catch (e: Exception) {
            if (!TextUtils.isEmpty(errorMessage)) {
                OkResult.Error(IOException(errorMessage))
            } else {
                OkResult.Error(handleExceptionMessage(e))
            }
        }
    }

    //处理Api错误，例如403Token过期 ；把BaseBean的数据转换为自定义的Result数据
    suspend fun <T : Any> handleApiErrorResponse(
        response: BaseBean<T>,
        successBlock: (suspend CoroutineScope.() -> Unit)? = null,
        errorBlock: (suspend CoroutineScope.() -> Unit)? = null
    ): OkResult<T> {

        return coroutineScope {
            //执行挂起函数
            if (response.code == BaseLibCore.successCode) {
                successBlock?.let { it() }

                if (response.data == null) {
                    //如果为空，就构造一个空的对象
                    OkResult.Error(RuntimeException("data为空"))
                } else {
                    OkResult.Success(response.data)
                }

            } else {
                errorBlock?.let { it() }
                OkResult.Error(IOException(response.message))
            }
        }
    }


    //处理自定义错误消息
    fun handleExceptionMessage(e: Exception): Exception {
        return when (e) {
            is UnknownHostException -> IOException(CommUtils.getString(R.string.error_domain_name))
            is JsonParseException -> IOException(CommUtils.getString(R.string.error_data_parsing))
            is ConnectException -> IOException(CommUtils.getString(R.string.error_network_connections))
            is HttpException -> IOException(CommUtils.getString(R.string.error_server_business))
            is SocketException -> IOException(CommUtils.getString(R.string.error_server_business))
            is SocketTimeoutException -> IOException(CommUtils.getString(R.string.error_network_timeout))
            is RuntimeException -> IOException(CommUtils.getString(R.string.error_running))
            else -> e
        }

    }

}